import BasicMapUtils from './BasicMapUtils'
import busIcon from 'assets/images/situational-awareness/bus-icon.png'
import { getRouteDetail, getRealTimeBusList } from 'api/situationAwareness/busWay/screenCenter'
import Bus from 'utils/eventBus'

const ol = window.ol
const TWEEN = window.TWEEN

class BusWay extends BasicMapUtils {
  constructor() {
    super()
    this.busWayList = [] // 用于存储数据
    this.layerBusWayList = [] // 用于存储图层数据
    this.busMarkerLayer = ''
    this.overlay = '' // 弹窗
    this.overlayPosition = '' // 弹窗的位置
    this.busMarkerLayer = '' // 公交图层
    this.acturalBusTimer = '' // 轮询公交定时器
    this.initBusWay()
  }

  // 公交线路模块初始化函数
  initBusWay() {
    // 线路切换监听
    Bus.$off('onChangeBusWay', this.getRouteDetail.bind(this))
    Bus.$on('onChangeBusWay', this.getRouteDetail.bind(this))

    // 驾驶员详情弹窗 弹出监听
    Bus.$off('showBusWayDriveCb', this.showBusWayDriverDialog.bind(this))
    Bus.$on('showBusWayDriverCb', this.showBusWayDriverDialog.bind(this))
    // 交互事件初始化
    this.initBusWayInteraction()

    // 加一条初始化数据
    this.getRouteDetail({ routeId: '20000083', segmentId: '100002' })
  }

  // 显示驾驶员弹窗
  showBusWayDriverDialog ({ driverId }) {
    this.overlay && this.overlay.setPosition(undefined)
    this.overlay = this.createOverlay({
      htmlElement: document.querySelector('.driver-info-dialog'),
      position: this.overlayPosition
    })
    this.map.addOverlay(this.overlay)
    Bus.$emit('showBusWayDriverDialog', { driverId })
  }

  // 获取某条线路上的实时车辆
  async getRealTimeBusList ({ routeId }) {
    this.map.removeLayer(this.busMarkerLayer)
    const params = {
      routeId
    }
    try {
      const res = await getRealTimeBusList(params)
      console.log('公交线路-获取线路上的实时公交', res)
      if (res.data && res.data.length > 0) {
        this.createActuralBus(res.data)
      }
    } catch (err) {
      console.error('公交线路-获取线路上的实时公交', err)
    } finally {
      this.acturalBusTimer = setTimeout(() => {
        this.getRealTimeBusList({ routeId })
      }, 10000)
    }
  }

  // 绘制实时车辆
  createActuralBus (busList) {
    const featureList = []
    busList.forEach(bus => {
      const { latitude: startLat, longitude: startLng, xyzwd: endLat, xyzjd: endLng } = bus
      let rotation = 0
      let busLocation = new ol.geom.Point([0, 0])

      const feature = new ol.Feature({
        geometry: busLocation,
        userData: {
          ...bus,
          type: 'marker',
          subType: 'busMarker'
        }
      })

      const style = () => {
        const style = new ol.style.Style({
          image: new ol.style.Icon({
            scale: 0.2,
            anchor: [0.5, 1],
            src: busIcon,
            rotation: rotation
          })
        })

        return style
      }
      featureList.push(feature)
      feature.setStyle(style)
      animateLocation.call(this, { startLat, startLng, endLat, endLng })
      function animateLocation({ startLat, startLng, endLat, endLng }) {
        const dx = endLng - startLng
        const dy = endLat - startLat
        rotation = Math.atan2(dy, -dx) // 得到箭头方向角
        const [x, y] = this.coordTransform.wgs84tobd09(startLng, startLat)
        busLocation = new ol.geom.Point([x, y])
        this.coordTransform.convertGeoIntoMap(busLocation)
        feature.getGeometry().setCoordinates(busLocation.getCoordinates())
      }
    })

    const source = new ol.source.Vector({
      features: featureList
    })
    this.busMarkerLayer = new ol.layer.Vector({
      source: source
    })
    this.map.removeLayer(this.busMarkerLayer)
    this.map.addLayer(this.busMarkerLayer)
  }

  // 获取某一条公交线路站点详情
  async getRouteDetail ({ routeId, segmentId }) {
    this.acturalBusTimer && clearTimeout(this.acturalBusTimer)
    this.getRealTimeBusList({ routeId })
    const params = {
      routeId,
      segmentId
    }
    try {
      const res = await getRouteDetail(params)
      console.log('获取线路详情', res)
      const stationArr = []
      if (res.data && res.data.length > 0) {
        res.data.forEach(station => {
          const { lat, lon } = station
          if (lat && lon) {
            stationArr.push(station)
          }
        })
      }
      if (stationArr.length > 0) {
        this.busWayList = [stationArr]
        this.drawBusWay()
      }
    } catch (err) {
      console.error('获取线路详情', err)
    }
  }

  // 获取线路的中心点坐标并转化成百度墨卡托投影下的坐标 -> x，y
  getBusWayCenter (busWay) {
    if (busWay.length > 0) {
      if (busWay.length % 2 === 0) {
        const { lon, lat } = busWay[Math.floor(busWay.length / 2) - 1]
        const centerPoint = new ol.geom.Point([lon, lat])
        this.coordTransform.convertGeoIntoMap(centerPoint)
        return centerPoint.getCoordinates()
      } else {
        const { lon, lat } = busWay[Math.floor(busWay.length / 2)]
        const centerPoint = new ol.geom.Point([lon, lat])
        this.coordTransform.convertGeoIntoMap(centerPoint)
        return centerPoint.getCoordinates()
      }
    } else {
      const centerPoint = new ol.geom.Point(this.mapCenter)
      this.coordTransform.convertGeoIntoMap(centerPoint)
      return centerPoint.getCoordinates()
    }
  }

  // 清除公交线路
  removeBusWay () {
    this.layerBusWayList.forEach(busWay => {
      const { line, station } = busWay
      this.map.removeLayer(line)
      this.map.removeLayer(station)
    })
    this.layerBusWayList = []
  }

  // 绘制公交线路
  drawBusWay () {
    this.removeBusWay()
    this.busWayList.forEach(item => {
      const lineLayer = this.createBusLine(item)
      const stationLayer = this.createBusStation(item)
      this.layerBusWayList.push({
        line: lineLayer,
        station: stationLayer
      })
    })

    this.layerBusWayList.forEach(busWay => {
      const { line, station } = busWay
      this.map.addLayer(line)
      this.map.addLayer(station)
    })

    const center = this.getBusWayCenter(this.busWayList[this.busWayList.length - 1] || [])
    this.mapView.animate({
      center: center,
      zoom: 14
    })
  }

  // 绘制公交线路-基础方法
  createBusLine (busway) {
    let lineArr = []
    busway.forEach(station => {
      const { lon, lat } = station
      const [x, y] = this.coordTransform.wgs84tobd09(lon, lat)
      lineArr.push([x, y])
    })
    lineArr = new ol.geom.LineString(lineArr)
    this.coordTransform.convertGeoIntoMap(lineArr)
    const { lineLayer: layer } = this.createLineWithDirection({ lineArr: lineArr.getCoordinates(), width: 6 })
    return layer
  }

  // 绘制公交站点-基础方法
  createBusStation (busway) {
    const style = new ol.style.Style({
      image: new ol.style.Circle({
        radius: 4,
        fill: new ol.style.Fill({ color: '#009A2B' }),
        stroke: new ol.style.Stroke({
          color: 'white',
          width: 3
        })
      })
    })
    const featureList = []
    busway.forEach(station => {
      const { lon: wgslng, lat: wgslat } = station
      const [lng, lat] = this.coordTransform.wgs84tobd09(wgslng, wgslat)
      const centerPoint = new ol.geom.Point([lng, lat])
      this.coordTransform.convertGeoIntoMap(centerPoint)
      const feature = new ol.Feature({
        userData: Object.assign({}, station, { type: 'marker' }),
        geometry: centerPoint
      })
      feature.setStyle(style)
      featureList.push(feature)
    })
    const source = new ol.source.Vector({
      features: featureList
    })
    const layer = new ol.layer.Vector({
      source: source
    })
    return layer
  }

  // 公交线路模块
  initBusWayInteraction () {
    this.map.on('click', e => {
      const pixel = this.map.getEventPixel(e.originalEvent)
      const feature = this.map.forEachFeatureAtPixel(pixel, feature => {
        return feature
      })
      this.overlay && this.overlay.setPosition(undefined)
      this.overlayPosition = undefined
      if (feature) {
        if (feature.get('userData') && feature.get('userData').type && feature.get('userData').type === 'marker') {
          if (feature.get('userData').subType && feature.get('userData').subType === 'busMarker') {
            this.overlay = this.createOverlay({
              htmlElement: document.querySelector('.bus-info-dialog'),
              position: e.coordinate
            })
            this.overlayPosition = e.coordinate
            this.map.addOverlay(this.overlay)
            Bus.$emit('showBusWayBusInfoDialog', feature.get('userData'))
          } else {
            // 给站点添加弹窗事件
            this.overlay = this.createOverlay({
              htmlElement: document.querySelector('.station-info-dialog'),
              position: e.coordinate
            })
            this.overlayPosition = e.coordinate
            this.map.addOverlay(this.overlay)
            const { id } = feature.get('userData')
            Bus.$emit('showBusWayStationDialog', { id })
          }
        }
      }
    })
  }

  // 绘制实时车辆
  drawActualBus() {
    const actualLineArr = []
    // b3.forEach((item, index, arr) => {
    //   const { lng, lat } = item
    //   actualLineArr.push({ lng, lat })
    //   if (index < arr.length - 1) {
    //     const { lng: nextLng, lat: nextLat } = arr[index + 1]
    //     actualLineArr.push({ lng: (lng + nextLng) / 2, lat: (lat + nextLat) / 2 })
    //   }
    // })
    let currentLocation = 0
    let rotation = 0
    let busLocation = new ol.geom.Point([0, 0])

    const feature = new ol.Feature({
      geometry: busLocation
    })
    const style = () => {
      const style = new ol.style.Style({
        image: new ol.style.Icon({
          scale: 0.2,
          anchor: [0.5, 1],
          src: busIcon,
          rotation: rotation
        })
      })

      return style
    }
    feature.setStyle(style)
    animateLocation.call(this)
    const source = new ol.source.Vector({
      features: [feature]
    })
    const layer = new ol.layer.Vector({
      source: source
    })
    this.map.addLayer(layer)

    function animateLocation() {
      if (currentLocation === actualLineArr.length - 1) {
        const { lng: startLng, lat: startLat } = actualLineArr[currentLocation - 1]
        const { lng: endLng, lat: endLat } = actualLineArr[currentLocation]
        const dx = endLng - startLng
        const dy = endLat - startLat
        rotation = Math.atan2(dy, -dx) // 得到箭头方向角
        const [x, y] = this.coordTransform.wgs84tobd09(endLng, endLat)
        busLocation = new ol.geom.Point([x, y])
        this.coordTransform.convertGeoIntoMap(busLocation)
        feature.getGeometry().setCoordinates(busLocation.getCoordinates())
        // const [x1, y1] = feature.getGeometry().getCoordinates()
        // const [x2, y2] = busLocation.getCoordinates()
        // this.tweenTranslate({
        //   oldPosition: { x: x1, y: y1 },
        //   newPosition: { x: x2, y: y2 },
        //   updateCallBack: position => {
        //     const { x, y } = position
        //     feature.getGeometry().setCoordinates([x, y])
        //   }
        // })
        // currentLocation = 0
      } else {
        const { lng: startLng, lat: startLat } = actualLineArr[currentLocation]
        const { lng: endLng, lat: endLat } = actualLineArr[currentLocation + 1]
        const dx = endLng - startLng
        const dy = endLat - startLat
        rotation = Math.atan2(dy, -dx) // 得到箭头方向角
        const [x, y] = this.coordTransform.wgs84tobd09(startLng, startLat)
        busLocation = new ol.geom.Point([x, y])
        this.coordTransform.convertGeoIntoMap(busLocation)
        feature.getGeometry().setCoordinates(busLocation.getCoordinates())
        // const [x1, y1] = feature.getGeometry().getCoordinates()
        // const [x2, y2] = busLocation.getCoordinates()
        // this.tweenTranslate({
        //   oldPosition: { x: x1, y: y1 },
        //   newPosition: { x: x2, y: y2 },
        //   updateCallBack: position => {
        //     const { x, y } = position
        //     feature.getGeometry().setCoordinates([x, y])
        //   }
        // })
        currentLocation++
      }
      const timer = setTimeout(() => {
        if (currentLocation === actualLineArr.length - 1) {
          clearTimeout(timer)
        }
        animateLocation.call(this)
      }, 1000)
    }
  }

  // 两点之间移动绘制补间动画---可能不通用 要做补间动画自己研究一下自己写
  tweenTranslate({ oldPosition, newPosition, updateCallBack, completeCallBack }) {
    const tween = new TWEEN.Tween({
      x: oldPosition.x,
      y: oldPosition.y
    })
    tween.to({
      x: newPosition.x,
      y: newPosition.y
    }, 500)
    tween.onUpdate(position => {
      updateCallBack(position)
    })
    tween.onComplete(() => {
      completeCallBack && completeCallBack()
    })
    tween.easing(TWEEN.Easing.Linear.None)
    tween.start()
  }

  // 公交线路的帧动画
  busWayAnimate() {
    requestAnimationFrame(this.busWayAnimate.bind(this))
    TWEEN.update()
  }

  // 清除 busWay 模块
  removeBusWayModule () {
    this.acturalBusTimer && clearTimeout(this.acturalBusTimer)
  }
}

export default BusWay

// bk4上行线
// const bk4up = [
//   { name: '江南客运站', lng: 108.308622, lat: 22.768183 },
//   { name: '南宁经济开发区', lng: 108.307453, lat: 22.772862 },
//   { name: '南国花园', lng: 108.315091, lat: 22.782992 },
//   { name: '白沙亭江路口', lng: 108.322449, lat: 22.786539 },
//   { name: '白沙市场', lng: 108.327554, lat: 22.788203 },
//   { name: '白沙桥南', lng: 108.329402, lat: 22.789354 },
//   { name: '新兴苑', lng: 108.352969, lat: 22.797041 },
//   { name: '竹溪青山路口', lng: 108.359338, lat: 22.799865 },
//   { name: '市环保局', lng: 108.362609, lat: 22.801601 },
//   { name: '竹溪立交', lng: 108.374785, lat: 22.814403 },
//   { name: '长虹厢竹路口站', lng: 108.374873, lat: 22.845523 },
//   { name: '长虹翠竹路口西站', lng: 108.382676, lat: 22.847537 },
//   { name: '长虹翠竹路口东站', lng: 108.389634, lat: 22.850387 },
//   { name: '长虹凤凰岭路口站', lng: 108.397789, lat: 22.850341 },
//   { name: '长虹站北三支路口', lng: 108.409302, lat: 22.849391 },
//   { name: '长虹高坡岭路口', lng: 108.427188, lat: 22.851434 },
//   { name: '长虹三塘南路口', lng: 108.427188, lat: 22.851434 },
//   { name: '松柏长虹路口', lng: 108.433971, lat: 22.852208 },
//   { name: '南宁农产品交易中心', lng: 108.434988, lat: 22.850197 }
// ]

// const bk4down = [
//   { name: '南宁农产品交易中心', lng: 108.435029, lat: 22.850355 },
//   { name: '松柏长虹路口', lng: 108.431987, lat: 22.853415 },
//   { name: '长虹三塘南路口', lng: 108.424442, lat: 22.850956 },
//   { name: '长虹高坡岭路口', lng: 108.412353, lat: 22.849671 },
//   { name: '长虹站北三支路口', lng: 108.409302, lat: 22.849391 },
//   { name: '长虹凤凰岭路口站', lng: 108.397848, lat: 22.850401 },
//   { name: '长虹翠竹路口东站', lng: 108.389755, lat: 22.850528 },
//   { name: '长虹翠竹路口西站', lng: 108.382716, lat: 22.847592 },
//   { name: '长虹厢竹路口站', lng: 108.37474, lat: 22.845462 },
//   { name: '竹溪立交', lng: 108.374175, lat: 22.814417 },
//   { name: '市环保局', lng: 108.362654, lat: 22.802126 },
//   { name: '竹溪青山路口', lng: 108.359215, lat: 22.800144 },
//   { name: '新兴苑', lng: 108.351602, lat: 22.796908 },
//   { name: '白沙桥南', lng: 108.329258, lat: 22.78901 },
//   { name: '白沙市场', lng: 108.327408, lat: 22.788434 },
//   { name: '白沙亭江路口', lng: 108.322326, lat: 22.785996 },
//   { name: '南国花园', lng: 108.312833, lat: 22.782288 },
//   { name: '南宁经济开发区', lng: 108.307723, lat: 22.772219 },
//   { name: '江南客运站', lng: 108.308622, lat: 22.768183 }
// ]

// b3路上行线
// const b3 = [
//   { name: '南湖公园', lng: 108.342842, lat: 22.810566 },
//   { name: '星湖路北二里', lng: 108.339364, lat: 22.810027 },
//   { name: '星湖路北一里', lng: 108.335526, lat: 22.809509 },
//   { name: '七星古城路口', lng: 108.330907, lat: 22.809406 },
//   { name: '新民七星路口', lng: 108.324972, lat: 22.811504 },
//   { name: '新民东葛路口', lng: 108.324515, lat: 22.818723 },
//   { name: '新民民主路口', lng: 108.324159, lat: 22.822535 },
//   { name: '工人文化宫站', lng: 108.318715, lat: 22.822746 },
//   { name: '人民朝阳路口', lng: 108.314786, lat: 22.821154 },
//   { name: '人民解放路口', lng: 108.310098, lat: 22.819045 },
//   { name: '人民永宁路口', lng: 108.307876, lat: 22.818096 },
//   { name: '新阳路水街市场', lng: 108.304838, lat: 22.817881 },
//   { name: '新阳北大路口', lng: 108.301434, lat: 22.818904 },
//   { name: '新阳立交', lng: 108.297281, lat: 22.819445 },
//   { name: '龙腾路口', lng: 108.291441, lat: 22.819996 },
//   { name: '龙腾新阳路口', lng: 108.290971, lat: 22.817136 },
//   { name: '龙腾江北路口', lng: 108.28944, lat: 22.811799 },
//   { name: '雅里', lng: 108.28793, lat: 22.810503 },
//   { name: '雅里上坡', lng: 108.284853, lat: 22.809851 },
//   { name: '永和村', lng: 108.281643, lat: 22.812574 },
//   { name: '中兴桥北1', lng: 108.279905, lat: 22.814589 },
//   { name: '新阳明秀路口', lng: 108.28126, lat: 22.821193 },
//   { name: '市三医院', lng: 108.278668, lat: 22.823257 },
//   { name: '新阳站', lng: 108.274727, lat: 22.824555 }
// ]
